package com.atguigu.gmall.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.atguigu.gmall.bean.Person;
import com.atguigu.gmall.bean.UserAddress;
import com.atguigu.gmall.component.RequestContext;
import com.atguigu.gmall.service.AsyncService;
import com.atguigu.gmall.service.OrderService;
import com.atguigu.gmall.service.PersonService;
import com.atguigu.gmall.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 1、将服务提供者注册到注册中心（暴露服务）
 * 1）、导入dubbo依赖（2.6.2）\操作zookeeper的客户端(curator)
 * 2）、配置服务提供者
 * <p>
 * 2、让服务消费者去注册中心订阅服务提供者的服务地址
 *
 * @author lfy
 */
@Service
public class OrderServiceImpl implements OrderService {

    public static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

    //@Autowired
    @Reference(loadbalance = "random", timeout = 1000, validation = "true") //dubbo直连
            UserService userService;

    @Reference(loadbalance = "roundrobin", stub = "com.atguigu.gmall.service.impl.PersonServiceStub", filter = "traceId")
    PersonService personService;

    @Reference(async = true)
    AsyncService asyncService;

    @HystrixCommand(fallbackMethod = "hello")
    @Override
    public List<UserAddress> initOrder(@NotNull String userId) {
        // TODO Auto-generated method stub
        System.out.println("用户id：" + userId);
        //1、查询用户的收货地址
        List<UserAddress> addressList = userService.getUserAddressList(userId);
        return addressList;
    }

    @HystrixCommand(fallbackMethod = "orderFallBack")
    @Override
    public List<Person> doOrder(String orderId) {
        log.info("service get traceId {}", RequestContext.getTraceId());
        List<Person> persons = personService.getPersonListByOrderId(orderId);
        for (Person person : persons) {
            System.out.println(person);
        }
        return persons;
    }

    public List<Person> orderFallBack(String orderId) {
        return Arrays.asList(new Person(99, "tom", "不详"));
    }


    public List<UserAddress> hello(String userId) {
        // TODO Auto-generated method stub

        return Arrays.asList(new UserAddress(10, "测试地址", "1", "测试", "测试", "Y"));
    }


    /**
     * dubbo 2.6.x 异步方法
     *
     * @param name
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     * @throws TimeoutException
     */
    @Override
    public String checkAsync(String name) throws ExecutionException, InterruptedException, TimeoutException {
        String res = asyncService.sayHi(name);
        System.out.println(res);
        //假异步，实际还是同步
        Future<String> future = RpcContext.getContext().getFuture();
        res = future.get(5, TimeUnit.SECONDS);
//        真异步，直接返回结果，在callback中处理业务
//        ResponseFuture future = ((FutureAdapter) RpcContext.getContext().getFuture()).getFuture();
//        future.setCallback(new ResponseCallback() {
//            @Override
//            public void done(Object response) {
//                System.out.println(response);
//            }
//
//            @Override
//            public void caught(Throwable exception) {
//                exception.printStackTrace();
//            }
//        });
        return res;
    }
}
